package common.server.utils;

import common.server.exception.ValidException;
import common.server.respcode.RespCodeService;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * 安全校验工具类
 *
 * @author zyz
 * @version [1.0.0, 2017-12-25 14:53:57]
 */
public class SecurityValidatorUtils {
	private static final String ENCODING = "UTF-8";
	private static final String MAC_NAME = "HmacSHA1";
	/**
	 * HMACSHA1加密key
	 */
	private static final String HMACSHA1_KEY = "12ge8SiULjolVLcg";
	private static final String md5_KEY = "com-bigwavn";
	private static final String ak_KEY = "wSrSuWvUVngHuhE9IYzKE1TzVks=";
	private static final Logger logger = LoggerFactory.getLogger(SecurityValidatorUtils.class);

	/**
	 * cid 校验
	 * @param cid  等同xk
	 * @throws ValidException
	 */
	public static void validateCid(String cid) throws  ValidException {
		try{
			if (StringUtils.isEmpty(cid) || cid.length() != 72) {
				throw  new ValidException(RespCodeService.COMM_SECUR_ERROR,"cid 长度不合法！");
			}
			String md5 = cid.substring(10, 26) + cid.substring(46, 62);
			String sha = cid.substring(0, 10) + cid.substring(26, 46)
					+ cid.substring(62, 72);
			String sha1CidStr = HmacSHA1Encrypt(md5, HMACSHA1_KEY);

			if (!sha1CidStr.equals(sha)) {
				logger.error("CID validate error: cid:{},sha1CidStr:{}", cid,
						sha1CidStr);
				throw  new ValidException(RespCodeService.COMM_SECUR_ERROR,"cid 校验不合法！");
			}
		}catch (Throwable e){
          throw  e instanceof ValidException ? (ValidException)e: new ValidException(RespCodeService.COMM_SECUR_ERROR,"cid 校验不合法！");
		}
	}

	/**
	 * xs 校验 xs，请求url+http body+私有字符串（com-bigwavn）。md5
	 * @param url  请求url
	 * @param reqBody http body
	 * @param xs 从http header中获取
	 * @throws ValidException
	 */
	public static void validateXs(String url, String reqBody, String xs) throws ValidException {
		try{
			if (StringUtils.isEmpty(xs) || xs.length() != 32) {
				throw  new ValidException(RespCodeService.COMM_SECUR_ERROR,"xs 长度不合法！");
			}
			String body = url + reqBody + md5_KEY;
			String md5Str = DigestUtils.md5Hex(body);

			if (!md5Str.equalsIgnoreCase(xs)) {
				logger.error("XS validate error: body:{},xs:{},md5:{}", body,xs,md5Str);
				throw  new ValidException(RespCodeService.COMM_SECUR_ERROR,"xs 校验不合法！");
			}
		}catch (Throwable e){
			throw  e instanceof ValidException ? (ValidException)e: new ValidException(RespCodeService.COMM_SECUR_ERROR,"xs 校验不合法！");
		}
	}

	/**
	 * ak 校验
	 * @param ak android特有签名
	 * @throws ValidException
	 */
	public static void validateXs(String ak) throws ValidException {
		try{
			if (StringUtils.isEmpty(ak) || ak.length() != 28) {
				throw  new ValidException(RespCodeService.COMM_SECUR_ERROR,"ak 长度不合法！");
			}
			if (!ak.equals(ak_KEY)) {
				logger.error("AK validate error: ak:{},key:{}", ak, ak_KEY);
				throw  new ValidException(RespCodeService.COMM_SECUR_ERROR,"ak 校验不合法！");
			}
		}catch (Throwable e){
			throw  e instanceof ValidException ? (ValidException)e: new ValidException(RespCodeService.COMM_SECUR_ERROR,"ak 校验不合法！");
		}
	}

	/**
	 *
	 * @param encryptText
	 * @param encryptKey
	 * @return
	 * @throws Exception
	 */
	public static String HmacSHA1Encrypt(String encryptText, String encryptKey)
			throws Exception {
		byte[] data = encryptKey.getBytes(ENCODING);
		// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
		SecretKey secretKey = new SecretKeySpec(data, MAC_NAME);
		// 生成一个指定 Mac 算法 的 Mac 对象
		Mac mac = Mac.getInstance(MAC_NAME);
		// 用给定密钥初始化 Mac 对象
		mac.init(secretKey);
		byte[] text = encryptText.getBytes(ENCODING);
		// 完成 Mac 操作
		return Hex.encodeHexString(mac.doFinal(text));
	}

	public static void main(String[] args) {
		String kk = "{\"ak\":\"wSrSuWvUVngHuhE9IYzKE1TzVks=\",\"appChannel\":\"1\",\"appVersion\":\"5.000\",\"cid\":\"a4310e7a6da877b5a2698d1a0d8a20597821169ae2a7430c360c79d137d90848a7086903\",\"cityCode\":\"10031\",\"deviecId\":\"b17287bc-912f-4580-a601-983cd38e2b83\",\"enlv\":\"0\",\"gpslevel\":\"200\",\"imei\":\"863968039804368\",\"imsi\":\"460002462781632\",\"laccid\":\"37107#151260162\",\"ljloaction\":\"0.0#0.0\",\"mcc\":\"460\",\"model\":\"Redmi 4\",\"os\":\"Android\",\"osVersion\":\"6.0.1\",\"reqBody\":{\"os\":\"1\",\"cityCode\":\"10031\"},\"signSt\":\"j5dgTE4Y/+X3vHDJnRgz5MNbAdo=\",\"sip\":\"fe80::9c59:89ff:fe21:4b9d%dummy0\",\"smac\":\"02:00:00:00:00:00\",\"sration\":\"1080x1920\",\"sstype\":\"WIFI\",\"swstrong\":\"0#0\",\"tel\":\"BQOSefyJ32ZyYJbOu4GylqEsEWjwsCaLYve+FmF0gPQUdQzGhCkrKtQOcdbs4X3VosWhp0IBI42ZEkvmRwmHmDqsIuZCYcpQpDV9nXxNOsWpC+6dT7mUbKNlUtqhSfdzUBarNOpqsqiKOIdLXlPs7N5LJNufdsOQhYuCBq85enA=\",\"time\":\"2017-12-29 21:31:28:788\"}";
		try {

			String pp = "http://192.168.7.71:8001/hlj-db-server/emotion/getEmotion"
					+ kk + md5_KEY;

			System.out.println(pp);
			System.out.println(DigestUtils.md5Hex(pp));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
